#include <windows.h>
#include "MySQL/mysql.h"

#include "CDb.h"
#include "CConsole.h"
#include "CModifier.h"
#include "CSemaphore.h"
#include "CWeaponItem.h"

CWeaponItem::CWeaponItem(unsigned short itemID) {
	m_reqLvl = 1;
	m_modelID = 0;
	m_subModelID = 0;
	m_equipSlotID = SLOT_MAIN;

	m_damage = 1;
	m_delay = 999;

	modList.clear();

	modListSemaphore = new CSemaphore(1);

	setType(ITEM_WEAPON);
	setId(itemID);
	setSkillType(WEAPON_NONE);

	loadStats();
}

CWeaponItem::~CWeaponItem() {
	modList.clear();
	lockModifierList();
	delete modListSemaphore;
}

void CWeaponItem::unlockModifierList(void)
{
	modListSemaphore->unlock();
	return;
}

void CWeaponItem::lockModifierList(void) 
{
	modListSemaphore->lock();
	return;
}

void CWeaponItem::loadStats() {
	MYSQL_RES * res;
	MYSQL_ROW row;
	char query[8192];
	unsigned long count;

	unsigned short newItemID = 0x0000;

	memset(query, 0, 8192);
	sprintf(query, "SELECT sw.Slot, sw.mID, sw.submid, sw.dmg, sw.dmgType, sw.delay, sw.skill, sw.Stack_Size, iv.BaseSell FROM stats_weapons AS sw LEFT JOIN item_values AS iv ON (sw.ItemID = iv.ItemID) WHERE sw.ItemID = %i", this->getId());
	count = (int) strlen(query);
	MYSQL * mysqlConn=CDb::getConn(); //get conn
	mysql_real_query(mysqlConn, query, count);
	res = mysql_store_result(mysqlConn);
	CDb::pushConn(mysqlConn); //release conn
	if(!res) {
		CConsole::outDebOnly("Error looking up weapon stats.");
	} else if(mysql_num_rows(res)){
		row = mysql_fetch_row(res);
		unsigned char databaseSlotID = atoi(row[0]);
		switch(databaseSlotID) {
			case DB_SLOTAMMO:
				setEquipSlotId(SLOT_AMMO);
				break;
			case DB_SLOTMAIN:
				setEquipSlotId(SLOT_MAIN);
				setModelId(atoi(row[1]) - 0x6000);
				if(atoi(row[2]) > 0)
					setSubModelId(atoi(row[2]) - 0x6000);
				break;
			case DB_SLOTOFFHAND:
				setEquipSlotId(SLOT_OFF);
				break;
			case DB_SLOTRANGED:
				setEquipSlotId(SLOT_RANGED);
				setModelId(atoi(row[1]) - 0x8000);
				if(atoi(row[2]) > 0)
					setSubModelId(atoi(row[2]) - 0x8000);
				break;
		}
		setDamage(atoi(row[3]));
		setDmgType(atoi(row[4]));
		setDelay(atoi(row[5]));
		setSkillType(atoi(row[6]));
		setStackSize(atoi(row[7]));
		setSellPrice(atoi(row[8]));
		// rest are modifiers.  to be added
		loadModifiers();
		loadAdditionalModifiers();
	}
	mysql_free_result(res);
}

void CWeaponItem::setModelId(unsigned short modelID) {
	m_modelID = modelID;
}

unsigned short CWeaponItem::getModelId() {
	return m_modelID;
}

void CWeaponItem::setSubModelId(unsigned short subModelID) {
	m_subModelID = subModelID;
}

unsigned short CWeaponItem::getSubModelId() {
	return m_subModelID;
}

void CWeaponItem::setReqLvl(unsigned char level) {
	m_reqLvl = level;
}

unsigned char CWeaponItem::getReqLvl() {
	return m_reqLvl;
}

void CWeaponItem::setEquipSlotId(unsigned char equipSlotID) {
	m_equipSlotID = equipSlotID;
}

unsigned char CWeaponItem::getEquipSlotId() {
	return m_equipSlotID;
}

void CWeaponItem::addMod(unsigned char modifier, char amount) {
	CModifier * newMod = new CModifier;
	newMod->setModID(modifier);
	newMod->setModAmount(amount);
	lockModifierList();
	modList.push_back(newMod);
	unlockModifierList();
}

char CWeaponItem::getModAmount(unsigned char modifier) {
	lockModifierList();
	for(unsigned char count = 0; count < modList.size(); count++) {
		CModifier * mod = modList.at(count);
		if(mod->getModID() == modifier) {
			unlockModifierList();
			return mod->getModAmount();
		}
	}
	unlockModifierList();
	return 0;
}

void CWeaponItem::setSkillType(unsigned char skillType) {
	m_skillType = skillType;
}

unsigned char CWeaponItem::getSkillType() {
	return m_skillType;
}


void CWeaponItem::setDelay(unsigned short delay) {
	m_delay = delay;
}

unsigned short CWeaponItem::getDelay() {
	return m_delay;
}

void CWeaponItem::setDamage(unsigned short damage) {
	m_damage = damage;
}

unsigned short CWeaponItem::getDamage() {
	return m_damage;
}

void CWeaponItem::setDmgType(unsigned short dmgType) {
	m_dmgType = dmgType;
}

unsigned short CWeaponItem::getDmgType() {
	return m_dmgType;
}

void CWeaponItem::loadModifiers() {
	
	MYSQL_RES * res;
	MYSQL_ROW row;
	char query[8192];
	unsigned long count;

	memset(query, 0, 8192);
	// Standard Modifiers
	sprintf(query, "SELECT `ItemID`, `DEF`, `HP`, `HP%%`, `ConvertMPtoHP`, `MP`, `MP%%`, `ConvertHPtoMP` ,`str`, `dex`, `vit`, `agi`, `int`, `mnd`, `chr`");
	sprintf(query, "%s, `Fire`, `Ice`, `Air`, `Earth`, `Thunder`, `Water`, `Light`, `Dark`, `Attack`, `Rattack`, `Accuracy`, `RAccuracy`, `Enmity`", query);
	sprintf(query, "%s FROM stats_weapons WHERE ItemID = %i", query, this->getId());
	count = (int) strlen(query);
	MYSQL * mysqlConn=CDb::getConn(); //get conn
	mysql_real_query(mysqlConn, query, count);
	res = mysql_store_result(mysqlConn);
	CDb::pushConn(mysqlConn); //release conn
	if(!res) {
		CConsole::outDebOnly("Error looking up standard weapon stats.");
	} else if(mysql_num_rows(res)){
		row = mysql_fetch_row(res);
		//Standard Modifiers start at 0x01(MOD_DEF) and are retrieved in order.
		for(unsigned char modType = 1; modType <= 27; modType++) {
			char modAmount = 0;
			modAmount = atoi(row[modType]);
			if( (modAmount > 0) || (modAmount < 0) )
				addMod(modType, modAmount);
		}
	}
	mysql_free_result(res);
}
void CWeaponItem::loadAdditionalModifiers() {
}
